<?php
// +----------------------------------------------------------------------
// | Description: 合同
// +----------------------------------------------------------------------
// | Author: Michael_xu | gengxiaoxu@5kcrm.com 
// +----------------------------------------------------------------------

namespace app\crm\controller;

use app\admin\controller\ApiCommon;
use think\Exception;
use think\Hook;
use think\Request;
use think\Db;

class Expence extends ApiCommon
{
    /**
     * 用于判断权限
     * @permission 无限制
     * @allow 登录用户可访问
     * @other 其他根据系统设置
     **/
    public function _initialize()
    {
        $action = [
            'permission' => [''],
            'allow' => ['get_customer','get_contract','add','index','detail',"get_finance_code"]
        ];
        Hook::listen('check_auth', $action);
        $request = Request::instance();
        $a = strtolower($request->action());
        if (!in_array($a, $action['permission'])) {
            parent::_initialize();
        }
    }

    /**
     * 模糊检索财务编号
     */
    public function get_finance_code(){
        $param = $this->param;
        $where["f.order_type"]="回款";
        $where["f.check_status"]="2";
        $where2['order_type'] = '成本变更';
        if(isset($param["order_sn"]) && $param["order_sn"]){
            $where2['receivables_code'] = $param['order_sn'];
            $where["order_sn"]=array("like","%{$param['order_sn']}%");
        }else{
            return resultArray(['data' => []]);
        }
        $data=DB::name("crm_finance")->alias("f")
            ->join("crm_contract c","c.contract_id=f.contract_id")
            ->where($where)
            ->field("f.order_sn,relation_id receivable_id,c.name customer_name,f.contract_id,f.crm_oeseng,f.customer_id")->limit(20)->select();
        if($data){
            foreach ($data as $k=>$v){
                
                //退款退回业绩
                $calculate=db("crm_finance")->where(["order_type"=>"退款","receivables_code"=>$v['order_sn'],"check_status"=>2])->sum("calculate");
                //实际退款金额(不含追回金额)
                $should_refund_money=db("crm_finance")->where(["order_type"=>"退款","receivables_code"=>$v['order_sn'],"check_status"=>2])->sum("should_refund_money");
                // 成本变更
                $crm_oesengg = DB::name("crm_finance")->where(['order_type'=>'成本变更','receivables_code'=>$v['order_sn']])->where(["check_status"=>["in",[0,1,2]]])->sum('crm_oeseng');
                // 已报销
                $expenseMoneySum=db("crm_finance")->where(["receivables_code"=>$v["order_sn"],"order_type"=>"报销","check_status"=>["in",[0,1,2]]])->sum("reimburse_money");//待已报销金额
                $data[$k]["crm_oeseng"] = bcsub(bcadd($data[$k]["crm_oeseng"],$crm_oesengg,2),bcadd($should_refund_money,$calculate,2),2);
                $data[$k]["max_expense_money"]=bcsub($data[$k]["crm_oeseng"],$expenseMoneySum,2);//最大可报销金额
            }
        }
        return resultArray(['data' => $data]);
    }
    /**
     * 获取客户列表
     */
    public function get_customer(){
        $param = $this->param;
        if(isset($param["customer_name"]) && $param["customer_name"]){
            $where["name"]=array("like","%{$param['customer_name']}%");
        }else{
            return resultArray(['data' => []]);
        }
        $data=DB::name("crm_customer")->where($where)->field("customer_id,name")->limit(20)->select();
        return resultArray(['data' => $data]);
    }
    /**
     * 根据客户id该客户下面所有合同
     */
    public function get_contract(){
        $param = $this->param;
        $where["check_status"]=2;
        if(is_numeric($param["customer_id"])){
            $where["customer_id"]=$param["customer_id"];
        }else{
            return resultArray(['data' => []]);
        }
        $data=DB::name("crm_contract")->where($where)->field("contract_id,name,num")->limit(20)->select();
        return resultArray(['data' => $data]);
    }

    /**
     * @param int $money
     * @param string $department
     * @param int $is_butler
     * 获取符合的条件的报销审批
     */
    private function getExamineCategory($money=0,$department="",$is_butler=0,$structure_id){
        $expenceExamine=db("oa_examine_category")
            ->where(["title"=>["like","%报销%"],"status"=>1,"is_deleted"=>0])
            ->field("category_id,structure_ids,department,money,butler")->order("money desc")->select();//报销
        if($expenceExamine){
            foreach ($expenceExamine as $k=>$v){
                $structure=$v["structure_ids"]?in_array($structure_id,explode(',',$v["structure_ids"])):"1";
                if($v["money"]<=$money && ($v["department"]==$department || $v["department"]=="全部") && ($v["butler"]==$is_butler || $v["butler"]=="全部") && $structure){
                    return $v["category_id"];
                }
            }
        }
        return "";
    }
    /**
     * 新增一个批量报销单
     */
    public function add(){
        $param = $this->param;
        $userInfo = $this->userInfo;
        Db::startTrans();
        try{
            $isButler = db('admin_access')->where(["user_id"=>$userInfo["id"],"group_id"=>32])->find();//管家
            $is_butler=$isButler?"管家":"非管家";
            $categoryId=$this->getExamineCategory($param["total_money"],$param["department"],$is_butler,$userInfo->structure_id);
            if(!$categoryId){
                return resultArray(['error' =>"报销新增失败！没有符合条件的审批！"]);
            }
            //新增审批流程
            $examineStep=DB::name("oa_examine_category")->alias("c")
                ->join("admin_examine_step s","c.flow_id=s.flow_id")
                ->join("admin_examine_flow f","c.flow_id=f.flow_id")
                ->where(["c.category_id"=>$categoryId])->field("f.config,s.flow_id,s.status,s.user_id,s.order_id,s.relation")->order("s.order_id asc")->find();
            if ($examineStep['config'] == 1) {
                //固定审批流
                $examineStepModel = new \app\admin\model\ExamineStep();
                $nextStepData = $examineStepModel->nextStepUser($userInfo['id'], $examineStep['flow_id'], 'oa_examine', 0, 0, 0);
                $check_user_id = $nextStepData['next_user_ids'] ? : '';
                $param['order_id'] = 1;
            } else {
                return resultArray(['error' =>"报销新增失败！没有符合条件的审批！"]);
            }
            //添加审批
            $examineInsertData=[
                "category_id"=>$categoryId,
                "content"=>"{$userInfo["realname"]}报销{$param["total_money"]}",
                "remark"=>"报销",
                "money"=>$param["total_money"],
                "create_user_id"=>$userInfo["id"],
                "check_user_id"=>is_array($check_user_id) ? ','.implode(',',$check_user_id).',' : $check_user_id,
                "flow_id"=>$examineStep["flow_id"],
                "order_id"=>$examineStep["order_id"],
                "create_time"=>time(),
                "update_time"=>time(),
            ];
            $examineId=Db::name("oa_examine")->insertGetId($examineInsertData);
            //报销信息
            $expenceInsertData=[
                "department"=>$param["department"],//报销部门，所属事业部
                "customer_id"=>0,//报销客户
                "user_id"=>$userInfo["id"],//报销人id
                "user_name"=>$userInfo["realname"],//报销人姓名
                "total_money"=>$param["total_money"],//总报销金额
                "upper"=>$param["upper"],//大写金额
                "payee"=>$param["payee"],//收款人
                "opening_bank"=>$param["opening_bank"],//开户行
                "bank_number"=>$param["bank_number"],//银行卡号
                "attachment"=>$param["attachment"],//附件
                "created_time"=>date("Y-m-d H:i:s"),
                "upload_time"=>date("Y-m-d H:i:s"),
                "examine_id"=>$examineId,//审批流程id
            ];
            $expenceId=Db::name("crm_expence")->insertGetId($expenceInsertData);
            //报销详情
            $details=$param["detail"];
            $contacts_ids=[];
            $receivables_code_arr=[];
            if($details && is_array($details)){
                foreach ($details as $detail){
                    $receivablesInfo=Db::name("crm_finance")->where(["order_type"=>"回款","check_status"=>"2","order_sn"=>$detail["order_sn"]])
                        ->field("customer_id,contract_id,relation_id receivable_id")->find();
                    if(!$receivablesInfo){
                        throw new Exception("回款单:{$detail['order_sn']}不存在！");
                    }
                    
                    // 回款单成本
                    $return_crm_oeseng = db("crm_finance")->where(["order_sn"=>$detail["order_sn"],"check_status"=>2])->sum("crm_oeseng");
                    // 成本变更
                    $change_crm_oesengg = DB::name("crm_finance")->where(["order_type"=>"成本变更","receivables_code"=>$detail['order_sn']])->where(["check_status"=>["in",[0,1,2]]])->sum('crm_oeseng');
                    //退款退回业绩
                    $calculate=db("crm_finance")->where(["order_type"=>"退款","receivables_code"=>$detail['order_sn'],"check_status"=>2])->sum("calculate");
                    //实际退款金额(不含追回金额)
                    $should_refund_money=db("crm_finance")->where(["order_type"=>"退款","receivables_code"=>$detail['order_sn'],"check_status"=>2])->sum("should_refund_money");
                    $crm_oeseng = bcadd($return_crm_oeseng,$change_crm_oesengg,2);
                    $crm_oeseng = bcsub($crm_oeseng,bcadd($should_refund_money,$calculate,2),2);
                    // 已报销
                    $expenseMoneySum=db("crm_finance")->where(["receivables_code"=>$detail["order_sn"],"order_type"=>"报销","check_status"=>["in",[0,1,2]]])->sum("reimburse_money");//待已报销金额
                    $max_expense_money = bcsub($crm_oeseng,$expenseMoneySum,2);
                    
                    if($detail['money'] > $max_expense_money) {
                        throw new Exception("该订单最大可报销".$max_expense_money);
                    }
                    
                    if(!in_array($receivablesInfo["contract_id"],$contacts_ids)){
                        $contacts_ids[]=$receivablesInfo["contract_id"];
                    }
                    $expenceDetailInsertData=[
                        "expence_id"=>$expenceId,//
                        "order_sn"=>$detail["order_sn"],//回款编号
                        "customer_name"=>$detail["customer_name"],//客户名称
                        "contract_id"=>$receivablesInfo["contract_id"],//合同订单id
                        "receivable_id"=>$receivablesInfo["receivable_id"],//回款id
                        "cost_money_all"=>$detail["cost_money_all"],//成本总金额
                        "cost_money"=>$detail["cost_money"],//可报销金额
                        "money"=>$detail["money"],//报销金额
                        "type"=>$detail["expense_type"],//报销类型
                        "ramark"=>$detail["ramark"],//办件事项备注
                    ];
                    $receivables_code_arr[]=$detail["order_sn"];
                    //数据中心添加数据
                    $financeData=[
                        "create_user_id"=>$userInfo["id"],//发起人
                        "customer_id"=>$receivablesInfo["customer_id"],//客户名称ID
                        "contract_id"=>$receivablesInfo["contract_id"],//订单编号ID
                        "receivables_code"=>$detail["order_sn"],//原回款的订单编号
                        "relation_id"=>$examineId,//关联ID、type为2回款时关联receivables_id，2则examine_id
                        "department"=>Db::name("crm_contract")->where(["contract_id"=>$receivablesInfo["contract_id"]])->value("crm_kfhgfp"),//所属部门
                        "order_type"=>"报销",//订单类型（回款、退款、成本变更、报销）
                        "reimburse_money"=>$detail["money"],//报销金额
                        "expense_type"=>$detail["expense_type"],//报销类型
                        "remarks"=>$detail["ramark"],//办件事项备注
                        "calculate_month"=>date("Y-m",time()),//业绩核算月份只针对回款和退款
                        "created_time"=>date("Y-m-d H:i:s"),//(回款、成本变更、退款、报销)时间
                    ];
                    Db::name("crm_finance")->insert($financeData);
                    Db::name("crm_expence_detail")->insert($expenceDetailInsertData);
                }
            }
            //更新
            Db::name("crm_expence")->where(["id"=>$expenceId])->update(["order_sn"=>implode(",",$receivables_code_arr)]);
            //审批关联数据
            $examineRelationInsertData=[
                "examine_id"=>$examineId,
                "contract_ids"=>",".implode(",",$contacts_ids).",",
                "create_time"=>time(),
            ];
            Db::name("oa_examine_relation")->insert($examineRelationInsertData);
            Db::commit();
            return resultArray(['data' => '报销新增成功！']);
        }catch (Exception $e){
            Db::rollback();
            return resultArray(['error' =>$e->getMessage()]);
        }
    }
    /**
     * 修改批量报销
     */
    public function update(){
        $param = $this->param;
        $expence=Db::name("crm_expence")->where(["id"=>$param["id"],"status"=>["in",array("0","3","4")]])->find();//只允许审批拒绝和撤回的报销单修改
        if(!$expence) return resultArray(['error' => "该报销单不存在或者不可修改！"]);
        //报销信息
        $userInfo = $this->userInfo;
        Db::startTrans();
        try{
            $expenceUpdateData=[
                "department"=>$param["department"],//报销部门，所属事业部
                "customer_id"=>0,//报销客户
                "user_id"=>$userInfo["id"],//报销人id
                "user_name"=>$userInfo["realname"],//报销人姓名
                "total_money"=>$param["total_money"],//总报销金额
                "upper"=>$param["upper"],//大写金额
                "payee"=>$param["payee"],//收款人
                "status"=>0,//0待审核
                "opening_bank"=>$param["opening_bank"],//开户行
                "bank_number"=>$param["bank_number"],//银行卡号
                "attachment"=>$param["attachment"],//附件
                "upload_time"=>date("Y-m-d H:i:s"),
            ];
            Db::name("crm_expence")->where(["id"=>$expence["id"]])->update($expenceUpdateData);
            //修改审批流程
            $examineStep=DB::name("oa_examine")->alias("c")
                ->join("admin_examine_step s","c.flow_id=s.flow_id")
                ->join("admin_examine_flow f","c.flow_id=f.flow_id")
                ->where(["c.examine_id"=>$expence["examine_id"]])->field("f.config,s.flow_id,s.status,s.user_id,s.order_id,s.relation")->order("s.order_id asc")->find();
            if ($examineStep['config'] == 1) {
                //固定审批流
                $examineStepModel = new \app\admin\model\ExamineStep();
                $nextStepData = $examineStepModel->nextStepUser($userInfo['id'], $examineStep['flow_id'], 'oa_examine', 0, 0, 0);
                $check_user_id = $nextStepData['next_user_ids'] ? : '';
            } else {
                return resultArray(['error' =>"报销新增失败！没有符合条件的审批！"]);
            }
            $check_user_id = ','.implode(',',$check_user_id).',';
            
            Db::name("oa_examine")->where(["examine_id"=>$expence["examine_id"]])->update(["money"=>$param["total_money"],"content"=>"{$userInfo["realname"]}报销{$param["total_money"]}","check_status"=>0,"check_user_id"=>$check_user_id,"flow_user_id"=>"",'order_id'=>$examineStep["order_id"]]);
            //删除原有的审批记录
            Db::name("admin_examine_record")->where(["types"=>"oa_examine","types_id"=>$expence["examine_id"],"flow_id"=>$examineStep['flow_id']])->delete();
            //报销详情
            $details=$param["detail"];
            $contacts_ids=[];
            $receivables_code_arr=[];
            
            // 先删除所有数据
            Db::name("crm_finance")->where(["order_type"=>"报销","relation_id"=>$expence["examine_id"]])->delete();
                    
            if($details && is_array($details)){
                foreach ($details as $detail){
                    $receivablesInfo=Db::name("crm_finance")->where(["order_type"=>"回款","check_status"=>"2","order_sn"=>$detail["order_sn"]])
                        ->field("customer_id,contract_id,relation_id receivable_id")->find();
                    if(!$receivablesInfo){
                        throw new Exception("回款单:{$detail['order_sn']}不存在！");
                    }
                    if(!in_array($receivablesInfo["contract_id"],$contacts_ids)){
                        $contacts_ids[]=$receivablesInfo["contract_id"];
                    }
                    $expenceDetailInsertData=[
                        "expence_id"=>$expence["id"],
                        "order_sn"=>$detail["order_sn"],//回款编号
                        "customer_name"=>$detail["customer_name"],//客户名称
                        "contract_id"=>$receivablesInfo["contract_id"],//合同订单id
                        "receivable_id"=>$receivablesInfo["receivable_id"],//回款id
                        "cost_money_all"=>$detail["cost_money_all"],//成本总金额
                        "cost_money"=>$detail["cost_money"],//可报销金额
                        "money"=>$detail["money"],//报销金额
                        "type"=>$detail["expense_type"],//报销类型
                        "ramark"=>$detail["ramark"],//办件事项备注
                    ];
                    $receivables_code_arr[]=$detail["order_sn"];
                    //数据中心添加数据
                    $financeData=[
                        "create_user_id"=>$userInfo["id"],//发起人
                        "customer_id"=>$receivablesInfo["customer_id"],//客户名称ID
                        "contract_id"=>$receivablesInfo["contract_id"],//订单编号ID
                        "receivables_code"=>$detail["order_sn"],//原回款的订单编号
                        "relation_id"=>$expence["examine_id"],//关联ID、type为2回款时关联receivables_id，2则examine_id
                        "department"=>Db::name("crm_contract")->where(["contract_id"=>$receivablesInfo["contract_id"]])->value("crm_kfhgfp"),//所属部门
                        "order_type"=>"报销",//订单类型（回款、退款、成本变更、报销）
                        "reimburse_money"=>$detail["money"],//报销金额
                        "expense_type"=>$detail["expense_type"],//报销类型
                        "remarks"=>$detail["ramark"],//办件事项备注
                        "calculate_month"=>date("Y-m",time()),//业绩核算月份只针对回款和退款
                        "created_time"=>date("Y-m-d H:i:s"),//(回款、成本变更、退款、报销)时间
                    ];
                    $expenceDetail=Db::name("crm_expence_detail")->where(["order_sn"=>$detail["order_sn"],"expence_id"=>$expence["id"]])->field("id")->find();
                    
                    // 再重新写入
                    Db::name("crm_finance")->insert($financeData);
                    Db::name("crm_expence_detail")->where(["id"=>$expenceDetail["id"]])->update($expenceDetailInsertData);
                    // Db::name("crm_finance")->where(["order_type"=>"报销","relation_id"=>$expence["examine_id"]])->update($financeData);
                    // if($expenceDetail){
                    //     Db::name("crm_expence_detail")->where(["id"=>$expenceDetail["id"]])->update($expenceDetailInsertData);
                    //     Db::name("crm_finance")->where(["order_type"=>"报销","relation_id"=>$expence["examine_id"]])->update($financeData);
                    // }else{
                    //     Db::name("crm_finance")->insert($financeData);
                    //     Db::name("crm_expence_detail")->insert($expenceDetailInsertData);
                    // }
                }
                //清楚本次删除的数据
                Db::name("crm_expence_detail")->where(["order_sn"=>array("not in",$receivables_code_arr),"expence_id"=>$expence["id"]])->delete();
                //更新
                Db::name("crm_expence")->where(["id"=>$expence["id"]])->update(["order_sn"=>implode(",",$receivables_code_arr)]);
                //审批关联数据
                $examineRelationInsertData=[
                    "examine_id"=>$expence['examine_id'],
                    "contract_ids"=>",".implode(",",$contacts_ids).",",
                    "create_time"=>time(),
                ];
                Db::name("oa_examine_relation")->where(["examine_id"=>$expence['examine_id']])->update($examineRelationInsertData);
            }
            Db::commit();
            return resultArray(['data' => '批量报销修改成功！']);
        }catch (Exception $e){
            Db::rollback();
            return resultArray(['error' =>$e->getMessage()]);
        }
    }
    /**
     * 获取报销详情
     */
    public function detail(){
        $param = $this->param;
        $expence=Db::name("crm_expence")->where(["id"=>$param["id"]])->find();
        if($expence){
            $expence["crm_customer"]=Db::name("crm_customer")->where(["customer_id"=>$expence["customer_id"]])->field("customer_id,name")->find();
            $expenceDetails=Db::name("crm_expence_detail")->where(["expence_id"=>$expence["id"]])->select();
            $expence["detail"]=$expenceDetails;
            //审批记录
            $expence["examineRecord"]=Db::name("admin_examine_record")->alias("r")
                ->join("admin_user admin","admin.id=r.check_user_id","left")
                ->where(["r.types"=>"oa_examine","r.types_id"=>$expence["examine_id"]])
                ->order("r.record_id asc")
                ->field("admin.realname,r.status,FROM_UNIXTIME(r.check_time,'%Y-%m-%d %H:%i') as check_time,r.content")
                ->select();
        }
        return resultArray(['data' => $expence]);
    }

    /**
     * 报销列表
     * */
    public function index()
    {
        $PersonnelModel = model('Expence');
        $param = $this->param;
        $userInfo = $this->userInfo;
        $param['user_id'] = $userInfo['id'];
        $data = $PersonnelModel->getDataList($param);
        return resultArray(['data' => $data]);
    }

}
